<template>
  <el-container>
    <el-header>
      <span v-if="this.data.length !== 0">
        <el-button type="primary" @click="addPersonnelHandler">新增人员</el-button>
        <el-button type="warning" @click="editPersonnelHandler">修改人员</el-button>
        <el-button type="danger" @click="deletePersonnelHandler">删除人员</el-button>
        <el-button type="success" @click="exportEXCEL">导出</el-button>
      </span>
    </el-header>
    <el-main>
      <div v-if="this.data.length !== 0">
        <el-table
          align="center"
          :height="getTableHeight"
          :data="data"
          :row-key="data.dayOfMonth"
          :row-class-name="tableRowClassName"
          style="width: 200%">
          <el-table-column
            :label="month + '  排班'"
            fixed
            width="210">
            <template slot-scope="scope">
              <el-row type="flex" justify="space-around">
                <el-col :span="4">{{ scope.row.dayOfMonth + '号'}}</el-col>
                <el-col :span="6">
                  <b v-if="scope.row.weekDay === '周六' || scope.row.weekDay === '周日' " style="color: dodgerblue">{{ scope.row.weekDay }}</b>
                  <b v-else>{{ scope.row.weekDay }}</b>
                </el-col>
                <el-col :span="12" v-if="scope.row.holiday" align="right">
                  <b v-if="scope.row.holiday.holiday" style="color: dodgerblue">{{ scope.row.holiday.name }}</b>
                  <b v-else style="color: red">{{ scope.row.holiday.name }}</b>
                </el-col>
              </el-row>
              <el-row type="flex" justify="space-between">
                <el-col  :span="10">
                  <span align="center" style="color: blueviolet">上班: <b>{{ scope.row.workerIds.length }}</b> 人</span>
                </el-col>
                <el-col  :span="10">
                  <span align="center" style="color: chocolate">接车: <b>{{ scope.row.welcomeIds.length }}</b> 人</span>
                </el-col>
              </el-row>
            </template>
          </el-table-column>
          <el-table-column
            align="center"
            v-for="item in this.personnel"
            :key="item.id"
            :label="item.name + (item.state ? '':'(离开)')">
            <el-table-column
              align="center"
              :label="totalWorkDays(item.id)"
            >
              <template slot-scope="scope">
                <el-switch
                  active-color="blueviolet"
                  :value="scope.row.workerIds.includes(item.id)"
                  @change="workDaySwitch($event, item.id, scope.row.workerIds)"
                >
                </el-switch>
              </template>
            </el-table-column>
            <el-table-column
              align="center"
              :label="totalWelcomeDays(item.id)"
            >
              <template slot-scope="scope">
                <el-switch
                  active-color="chocolate"
                  :value="scope.row.welcomeIds.includes(item.id)"
                  @change="welcomeDaySwitch($event, item.id, scope.row.welcomeIds)"
                >
                </el-switch>
              </template>
            </el-table-column>
          </el-table-column>
        </el-table>
      </div>
      <div v-else>
        <p><el-tag type="warning">新建数据</el-tag></p>
        <br>
        <el-date-picker
          v-model="choiceMonth"
          type="month"
          value-format="yyyy-MM"
          format="yyyy 年 MM 月"
          placeholder="选择月">
        </el-date-picker>
        <el-button :disabled="!choiceMonth" type="warning" @click="initData">初始化数据</el-button>
        <br>
        <p><el-tag type="primary">导入数据</el-tag></p>
        <el-upload
          class="avatar-uploader"
          action=""
          :limit="1"
          accept=".json"
          :show-file-list="false"
          :before-upload="importJSON">
          <i class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
      </div>
    </el-main>

    <!-- 新增人员 -->
    <el-dialog :title="personnelDialog.title" :visible.sync="personnelDialog.visible" width="30%" :close-on-click-modal="false">
      <el-form :model="personnelDialog.form" :rules="personnelDialog.formRule" ref="personnelForm" label-width="80px">
        <el-form-item
          prop="name"
          label="姓名">
          <el-input v-model="personnelDialog.form.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item prop="state" label="状态" align="left">
          <template>
            <el-radio v-model="personnelDialog.form.state" :label="true">正常</el-radio>
            <el-radio v-model="personnelDialog.form.state" :label="false">离开</el-radio>
          </template>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer" align="center">
        <el-button @click="personnelDialog.visible = false">取 消</el-button>
        <el-button v-show="!personnelDialog.update" type="primary" @click="addPersonnel">增 加</el-button>
        <el-button v-show="personnelDialog.update" type="primary" @click="updatePersonnel">修 改</el-button>
      </div>
    </el-dialog>

    <!-- 新增列表弹出框 -->
    <el-dialog :title="personnelListDialog.title" :visible.sync="personnelListDialog.visible" width="30%" :close-on-click-modal="false">
      <el-table
        align="center"
        :data="personnel"
        :row-key="personnel.id"
        style="width: 100%">
        <el-table-column
          label="姓名"
          width="150">
          <template slot-scope="scope">
            <el-tag>{{scope.row.name}}</el-tag>
          </template>
        </el-table-column>
        <el-table-column
          prop="state"
          label="状态"
          width="150">
          <template slot-scope="scope">
            <b v-if="scope.row.state" style="color: green">正常</b>
            <b v-else style="color: gainsboro">离开</b>
          </template>
        </el-table-column>
        <el-table-column
          label="操作">
          <template slot-scope="scope">
            <el-button
              v-show="personnelListDialog.update"
              size="mini"
              type="warning"
              @click="handleUpdatePersonnel(scope.row)">修改
            </el-button>
            <el-button
              v-show="!personnelListDialog.update"
              size="mini"
              type="danger"
              @click="handleDeletePersonnel(scope.row)">删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <div slot="footer" class="dialog-footer" align="center">
        <el-button @click="personnelListDialog.visible = false">关闭</el-button>
      </div>
    </el-dialog>
  </el-container>
</template>

<script>
import axios from 'axios'
import FileSaver from 'file-saver'

export default {
  name: 'schedule',
  data () {
    return {
      personnelDialog: {
        title: '',
        visible: false,
        update: false,
        form: {
          id: undefined,
          name: '',
          state: true
        },
        formRule: {
          name: [
            {required: true, message: '请输入人员姓名', trigger: 'blur'}
          ],
          state: [
            {required: true, message: '请选择人员状态', trigger: 'blur'}
          ]
        }
      },
      personnelListDialog: {
        title: '',
        visible: false,
        update: undefined
      },
      month: '',
      jsonData: [],
      personnel: [],
      data: [],
      choiceMonth: ''
    }
  },
  computed: {
    getTableHeight () {
      return window.screen.availHeight * 0.73
    }
  },
  methods: {
    tableRowClassName ({row}) {
      if (row.weekDay === '周六' || row.weekDay === '周日' || row.holiday) {
        return 'specie-row'
      }
      return ''
    },
    totalWorkDays (personnelId) {
      // 计算指定id人员本月上班总天数
      let totalWorkDays = 0
      this.data.forEach(item => {
        if (item.workerIds.includes(personnelId)) {
          totalWorkDays++
        }
      })
      return '上班(' + totalWorkDays + '天)'
    },
    totalWelcomeDays (personnelId) {
      // 计算指定id人员本月上班总天数
      let totalWorkDays = 0
      this.data.forEach(item => {
        if (item.welcomeIds.includes(personnelId)) {
          totalWorkDays++
        }
      })
      return '接车(' + totalWorkDays + '天)'
    },
    workDaySwitch (newValue, personnelId, workerIds) {
      if (newValue) {
        workerIds.push(personnelId)
      } else {
        let index = workerIds.findIndex(item => item === personnelId)
        if (index > -1) {
          workerIds.splice(
            index,
            1
          )
        }
      }
    },
    welcomeDaySwitch (newValue, personnelId, welcomeIds) {
      if (newValue) {
        welcomeIds.push(personnelId)
      } else {
        let index = welcomeIds.findIndex(item => item === personnelId)
        if (index > -1) {
          welcomeIds.splice(
            index,
            1
          )
        }
      }
    },
    addPersonnelHandler () {
      // 设置添加人员的 id  取数据中最大人员id + 1
      let length = this.personnel.length
      let personnelId
      if (length === 0) {
        personnelId = 1
      } else {
        personnelId = this.personnel[this.personnel.length - 1].id + 1
      }
      this.personnelDialog.title = '新增人员'
      this.personnelDialog.form.id = personnelId
      this.personnelDialog.visible = true
    },
    addPersonnel () {
      this.$refs['personnelForm'].validate((valid) => {
        if (valid) {
          this.personnel.push(this.personnelDialog.form)
          this.personnelDialog.visible = false
          this.resetPage()
          this.personnelDialog.form = {
            id: undefined,
            name: '',
            state: undefined
          }
        } else {
          return false
        }
      })
    },
    resetPage () {
      this.data = []
      this.$nextTick(() => {
        this.data = this.jsonData.data
      })
    },
    editPersonnelHandler () {
      this.personnelListDialog.update = true
      this.showPersonnelList('修改人员')
    },
    deletePersonnelHandler () {
      this.personnelListDialog.update = false
      this.showPersonnelList('删除人员')
    },
    showPersonnelList (title) {
      this.personnelListDialog.title = title
      this.personnelListDialog.visible = true
    },
    handleUpdatePersonnel (row) {
      this.personnelDialog.title = '修改人员'
      this.personnelDialog.form = row
      this.personnelDialog.update = true
      this.personnelDialog.visible = true
    },
    handleDeletePersonnel (row) {
      this.$confirm(`确定要删除 ${row.name} 吗?删除人员后,该人员的排班数据都会一并删除!`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 删除人员排班数据
        let personnelId = row.id
        this.data.forEach(item => {
          let workerIds = item.workerIds
          let index = workerIds.findIndex(pId => pId === personnelId)
          if (index > -1) {
            workerIds.splice(
              index,
              1
            )
          }
          let welcomeIds = item.welcomeIds
          let index2 = welcomeIds.findIndex(pId => pId === personnelId)
          if (index2 > -1) {
            welcomeIds.splice(
              index2,
              1
            )
          }
        })
        // 删除人员
        let personnel = this.personnel
        let index3 = personnel.findIndex(item => item.id === personnelId)
        if (index3 > -1) {
          personnel.splice(
            index3,
            1
          )
        }
        this.resetPage()
      })
    },
    updatePersonnel () {
      this.personnelDialog.visible = false
      this.personnelDialog.update = false
      this.personnelDialog.form = {
        id: undefined,
        name: '',
        state: undefined
      }
    },
    initData () {
      this.jsonData = {
        personnel: [],
        data: []
      }
      this.data = this.jsonData.data
      this.personnel = this.jsonData.personnel
      this.month = this.choiceMonth
      // 查询节假日信息
      axios.get('http://timor.tech/api/holiday/year/' + this.choiceMonth)
        .then(({data}) => {
          if (data.code === 0) {
            // 正常返回 ,初始化日期/节假日
            let holidayArr = Object.keys(data.holiday)
            let choiceYYYYmm = this.choiceMonth.split('-')
            let YYYY = choiceYYYYmm[0]
            let MM = choiceYYYYmm[1]
            // 本月总天数
            let totalDays = new Date(YYYY, MM, 0).getDate()
            for (let day = 1; day <= totalDays; day++) {
              let dataOfDay = {
                dayOfMonth: day,
                weekDay: this.transferWeek(new Date(YYYY + '-' + MM + '-' + day).getDay()),
                workerIds: [],
                welcomeIds: []
              }
              let MMdd = MM + '-' + (day < 10 ? '0' + day : day)
              if (holidayArr.includes(MMdd)) {
                // 是节假日 或 调休日
                let holiday = data.holiday[MMdd]
                dataOfDay.holiday = holiday
              }
              this.data.push(dataOfDay)
            }
          } else {
            this.$message.error('初始化失败,日期接口故障!')
          }
        })
        .catch(error => {
          console.log(error)
        })
    },
    exportJSON () {
      // 将json转换成字符串
      const data = JSON.stringify(this.jsonData)
      const blob = new Blob([data], {type: ''})
      FileSaver.saveAs(blob, this.month + '.json')
    },
    exportEXCEL (res) {
      require.ensure([], () => {
        const { exportJsonToExcel } = require('../utils/Export2Excel.js')
        let tHeader = ['日期']
        let personnelArr = this.personnel.map(p => {
          let workNum = this.totalWorkDays(p.id)
          let welcomeNum = this.totalWelcomeDays(p.id)
          return `${p.name}(上班: ${workNum} 接车: ${welcomeNum})`
        })
        tHeader = tHeader.concat(personnelArr)
        tHeader.push('接车')
        tHeader.push('当天上班人数')
        const source = this.getSource(this.personnel, this.data)
        exportJsonToExcel(tHeader, source, this.month + '排班表')
        this.exportJSON()
      })
    },
    getSource (personnel, data) {
      let source = []
      let month = this.month.split('-')[1] * 1
      for (let i = 0; i < data.length; i++) {
        let arr = []
        const dataOfDay = data[i]
        arr.push(`${month}月${dataOfDay.dayOfMonth}日 ${dataOfDay.weekDay} ${dataOfDay.holiday ? dataOfDay.holiday.name : ''}`)
        const workerIds = dataOfDay.workerIds
        const welcomeIds = dataOfDay.welcomeIds
        let dayOfWelcome = ''
        for (let j = 0; j < personnel.length; j++) {
          if (workerIds.includes(personnel[j].id)) {
            arr.push('1')
          } else {
            arr.push('')
          }
          if (welcomeIds.includes(personnel[j].id)) {
            dayOfWelcome = personnel[j].name + '; '
          }
        }
        arr.push(dayOfWelcome)
        arr.push(workerIds.length)
        source.push(arr)
      }
      return source
    },
    // 导入json
    importJSON (file) {
      const reader = new FileReader()
      reader.readAsText(file)
      const _this = this
      _this.month = file.name.substring(0, 7)
      reader.onload = function () {
        // this.result为读取到的json字符串，需转成json对象
        _this.jsonData = JSON.parse(this.result)
        _this.personnel = _this.jsonData.personnel
        _this.data = _this.jsonData.data
      }
      return false
    },
    transferWeek (day) {
      let w
      switch (day) {
        case 0:
          w = '周日'
          break
        case 1:
          w = '周一'
          break
        case 2:
          w = '周二'
          break
        case 3:
          w = '周三'
          break
        case 4:
          w = '周四'
          break
        case 5:
          w = '周五'
          break
        case 6:
          w = '周六'
          break
      }
      return w
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  h1, h2 {
    font-weight: normal;
  }

  ul {
    list-style-type: none;
    padding: 0;
  }

  li {
    display: inline-block;
    margin: 0 10px;
  }

  a {
    color: #42b983;
  }

  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }
</style>
<style>

  .el-table .specie-row {
    background: oldlace;
  }
</style>
